package com.ruoyi.pm.util;

import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.pm.domain.ExcPort;
import com.ruoyi.pm.domain.ExcPortConfig;
import com.ruoyi.pm.domain.ExcPortHeader;
import com.ruoyi.pm.domain.SaasSupplierRequest;
import com.ruoyi.pm.service.IExcPortConfigService;
import com.ruoyi.pm.service.ISaasSupplierRequestService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author fangzhuan
 * @date 2022年02月17日 11:44
 */
@Component
public class SupplierUtil {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private IExcPortConfigService excPortConfigService;

    @Autowired
    private ISaasSupplierRequestService saasSupplierRequestService;

    @Autowired
    private ApplicationContext applicationContext;


    /**
     * 校验返回修改是否满足条件
     *
     * @param excPortConfig
     * @param supplierResponse
     * @return
     */
    /*public boolean updateCheck(ExcPortConfig excPortConfig, Map<String, Object> supplierResponse,Long portId) {
        //判断是否符合条件修改
        List<ExcPortUpdateCondition> excPortUpdateConditionList = excPortUpdateConditionService.selectListByPortConfig(portId,excPortConfig.getId());

        if (StringUtils.isNotNull(excPortUpdateConditionList) && excPortUpdateConditionList.size() > 0) {
            Map<Long, List<ExcPortUpdateCondition>> excPortUpdateConditionListMap = excPortUpdateConditionList.stream().collect(Collectors.groupingBy(excPortUpdateCondition -> excPortUpdateCondition.getGroupId()));
            ok: for (Map.Entry entry : excPortUpdateConditionListMap.entrySet()) {
                List<ExcPortUpdateCondition> excPortUpdateConditionMapList = (List) entry.getValue();
                boolean checkConfig = false;
                //这个里面循环都是or条件
                for (ExcPortUpdateCondition excPortUpdateCondition : excPortUpdateConditionMapList) {
                    String matchingValue = excPortUpdateCondition.getMatchingValue();
                    Object outFieldValueObj = jsonCashCalculateService.getFieldValue1(supplierResponse, excPortUpdateCondition.getOutFieldFormula());
                    if (StringUtils.isNull(outFieldValueObj) || "".equals(outFieldValueObj)) {
                        continue;
                    }
                    String outFieldValue = String.valueOf(outFieldValueObj);
                    //正则
                    if ("1".equals(excPortUpdateCondition.getMatchingType())) {
                        try {
                            checkConfig = outFieldValue.matches(matchingValue);
                        } catch (Exception e) {
                            throw new BusinessException("后台配置数据有误，请联系管理员处理。错误码：75530");
                        }

                    }
                    //比较
                    if ("2".equals(excPortUpdateCondition.getMatchingType())) {
                        String compareFlag = excPortUpdateCondition.getCompareFlag();
                        switch (compareFlag) {
                            case "=":
                                checkConfig = matchingValue.equals(outFieldValue);
                                continue;
                            case ">":
                                checkConfig = outFieldValue.compareTo(matchingValue) > 0 ? true : false;
                                continue;
                            case ">=":
                                checkConfig = outFieldValue.compareTo(matchingValue) >= 0 ? true : false;
                                continue;
                            case "<":
                                checkConfig = outFieldValue.compareTo(matchingValue) < 0 ? true : false;
                                continue;
                            case "<=":
                                checkConfig = outFieldValue.compareTo(matchingValue) <= 0 ? true : false;
                                continue;
                            case "in":
                                String[] split = matchingValue.split(",");
                                checkConfig = Arrays.asList(split).contains(outFieldValue);
                                continue;
                            case "not-in":
                                String[] split1 = matchingValue.split(",");
                                checkConfig = !Arrays.asList(split1).contains(outFieldValue);
                                continue;
                            default:
                                continue;
                        }
                    }
                    if(checkConfig){
                        continue ok;
                    }
                }
                if(!checkConfig){
                    return false;
                }
            }
        }
        return true;
    }*/


    /**
     * 组装请求报文
     *
     * @param excPort 接口配置对象
     * @return map
     */
    public Map<String, Object> assembleRequestBody(ExcPort excPort) {
        //1是出参
        List<ExcPortConfig> excPortConfigList = excPortConfigService.selectExcPortConfigListByPortIdAndType(excPort.getId(), "1");
        if (excPortConfigList == null && excPortConfigList.size() < 1) {
            return null;
        }
        //组装保司报文
        //定义一个返回map
        Map<String, Object> requestMap = new HashMap<>();
        List<ExcPortConfig> collect = excPortConfigList.stream().filter(excPortConfig -> excPortConfig.getParentId().equals(100L)).sorted(Comparator.comparing(ExcPortConfig::getOrderNum)).collect(Collectors.toList());
        for (ExcPortConfig excPortConfig : collect) {
            Object object = assemble(excPortConfig, excPortConfigList, excPort);
            if (StringUtils.isNotNull(object)) {
                requestMap.put(excPortConfig.getField(), object);
            }
        }
        return requestMap;
    }

    /**
     * 请求服务方接口
     *
     * @param excPort
     * @return java.lang.Object
     */
    public Map<String, Object> sendSupplierRequest(ExcPort excPort, Map<String, Object> supplierRequest,List<ExcPortHeader> excPortHeaderList) {
        //查询保司请求方法
        SaasSupplierRequest saasSupplierRequest = saasSupplierRequestService.selectSaasSupplierRequestById(excPort.getRequestId());
        String methodString = saasSupplierRequest.getReqMain();
        String springBeanName = methodString.substring(0, methodString.lastIndexOf("."));
        String methodName = methodString.substring(methodString.lastIndexOf(".") + 1);

        Class<?> clazz = null;
        try {

            clazz = Class.forName("com.ruoyi.pm." + springBeanName);

            Object service = applicationContext.getBean(clazz);

            Method method = clazz.getDeclaredMethod(methodName, ExcPort.class, Map.class, List.class); // 获取方法对象
            Object[] parameters = new Object[]{excPort, supplierRequest, excPortHeaderList}; // 构造参数

            return (Map<String, Object>) method.invoke(service, parameters);
        } catch (ClassNotFoundException e) {
            logger.error(e.getMessage());
        } catch (NoSuchMethodException e) {
            logger.error(e.getMessage());
        } catch (IllegalAccessException e) {
            logger.error(e.getMessage());
        } catch (InvocationTargetException e) {
            logger.error(e.getMessage());
        }
        return null;

    }

    public Object assemble(ExcPortConfig excPortConfig, List<ExcPortConfig> excPortConfigList, ExcPort excPort) {

        //类型是1的直接塞进返回map里
        if ("1".equals(excPortConfig.getFieldType())) {
            //去用公式取值
            return excPortConfig.getMappingFormula();
        }
        //类型是map 走递归
        if ("2".equals(excPortConfig.getFieldType())) {
            List<ExcPortConfig> collect = excPortConfigList.stream().filter(config -> excPortConfig.getId().equals(config.getParentId())).sorted(Comparator.comparing(ExcPortConfig::getOrderNum)).collect(Collectors.toList());
            Map<String, Object> outMap = null;
            if (StringUtils.isNotNull(collect) && collect.size() > 0) {
                outMap = new HashMap<>();
                for (ExcPortConfig config : collect) {

                    Object obj = assemble(config, excPortConfigList, excPort);

                    if (StringUtils.isNotNull(obj)) {
                        outMap.put(config.getField(), obj);
                    }
                }
            }
            return outMap;
        }
        //类型是List
        if ("3".equals(excPortConfig.getFieldType())) {
            List<ExcPortConfig> collect = excPortConfigList.stream().filter(config -> excPortConfig.getId().equals(config.getParentId())).sorted(Comparator.comparing(ExcPortConfig::getOrderNum)).collect(Collectors.toList());
            List<Object> supplierObjList = null;
            if (StringUtils.isNotNull(collect) && collect.size() > 0) {
                Map<String, Object> outMap = new HashMap<>();
                for (ExcPortConfig config : collect) {

                    Object obj = assemble(config, excPortConfigList, excPort);

                    if (StringUtils.isNotNull(obj)) {
                        outMap.put(config.getField(), obj);
                    }
                }
                if (StringUtils.isNotNull(outMap)) {
                    supplierObjList.add(outMap);
                }
            }
            return supplierObjList;
        }
        return null;
    }
}
